﻿//  ------------------------------------------------------------------------------------
//  Copyright (c) Microsoft Corporation
//  All rights reserved. 
//  
//  Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this 
//  file except in compliance with the License. You may obtain a copy of the License at 
//  http://www.apache.org/licenses/LICENSE-2.0  
//  
//  THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
//  EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR 
//  CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR 
//  NON-INFRINGEMENT. 
// 
//  See the Apache Version 2.0 License for specific language governing permissions and 
//  limitations under the License.
//  ------------------------------------------------------------------------------------

namespace Amqp
{
    using System;
    using System.Net.WebSockets;
    using System.Threading.Tasks;

    /// <summary>
    /// The factory to create <see cref="WebSocketTransport" /> client for address
    /// scheme "ws" and "wss".
    /// </summary>
    public class WebSocketTransportFactory : TransportProvider
    {
        readonly string subprotocol;

        /// <summary>
        /// Initializes a WebSocketTransportFactory object with the default subprotocol 'amqp'.
        /// </summary>
        public WebSocketTransportFactory()
            : this(WebSocketTransport.WebSocketSubProtocol)
        {
        }

        /// <summary>
        /// Initializes a WebSocketTransportFactory object with the specified subprotocol.
        /// </summary>
        /// <param name="subprotocol">The subprotocol used for WebSocket upgrade.</param>
        public WebSocketTransportFactory(string subprotocol)
        {
            this.subprotocol = subprotocol;
            this.AddressSchemes = new string[] { WebSocketTransport.WebSockets, WebSocketTransport.SecureWebSockets };
        }

        /// <summary>
        /// Gets or sets the delegate to update the ClientWebSocketOptions of the underlying WebSocket object.
        /// </summary>
        public Action<ClientWebSocketOptions> Options
        {
            get;
            set;
        }

        /// <summary>
        /// Creates a WebSocket transport for the given address.
        /// </summary>
        /// <param name="address">The address to connect.</param>
        /// <returns>An IAsyncTransport object representing the transport.</returns>
        public override async Task<IAsyncTransport> CreateAsync(Address address)
        {
            var wsTransport = new WebSocketTransport();
            await wsTransport.ConnectAsync(address, this.subprotocol, this.Options).ConfigureAwait(false);
            return wsTransport;
        }
    }
}